package site.beanyon.now.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import site.beanyon.now.constant.ResponseEnum;
import site.beanyon.now.model.dto.HttpResponse;
import site.beanyon.now.model.dto.UserDTO;
import site.beanyon.now.service.UserService;
import site.beanyon.now.util.StringUtils;

import java.util.Map;

/**
 * 用户控制器
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * 新用户注册
     *
     * @param params 包含账号tel及密码psw
     * @return 注册结果
     */
    @PostMapping("/sign-up")
    public HttpResponse signUp(@RequestBody Map<String, String> params) {
        String tel = params.get("tel");
        String psw = params.get("psw");

        // 对账号密码判空
        if (StringUtils.isEmpty(tel) || StringUtils.isEmpty(psw)) {
            // 账号或密码为空，返回错误提示
            return new HttpResponse(ResponseEnum.FAILED_SIGN_UP, null);
        }

        // 向数据库中插入用户
        boolean success = this.userService.insertUser(tel, psw, StringUtils.getRandomString());

        // 注册成功
        if (success) {
            return new HttpResponse(ResponseEnum.SUCCESS_SIGN_UP, null);
        }

        return new HttpResponse(ResponseEnum.UNKNOWN, null);
    }

    /**
     * 用户登录
     *
     * @param params 包含账号tel及密码psw
     * @return 登录结果
     */
    @PostMapping("/sign-in")
    public HttpResponse signIn(@RequestBody Map<String, String> params) {
        String tel = params.get("tel");
        String psw = params.get("psw");

        // 使用Shiro进行认证
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(tel, psw);

        // 抛出异常表示认证失败，未抛出异常表示认证成功
        try {
            subject.login(token);
            UserDTO userDTO = (UserDTO) subject.getPrincipal();
            userDTO.setSessionId((String) subject.getSession().getId());
            return new HttpResponse(ResponseEnum.SUCCESS_SIGN_IN, userDTO);
        } catch (UnknownAccountException e) {
            // 账号不存在
            return new HttpResponse(ResponseEnum.ACCOUNT_NOT_EXISTS, null);
        } catch (IncorrectCredentialsException e) {
            // 密码错误
            return new HttpResponse(ResponseEnum.PASSWORD_INCORRECT, null);
        }
    }

    /**
     * 获取用户有登录行为的天数
     *
     * @return 用户有登录行为的天数
     */
    @GetMapping("/login-day-count")
    public HttpResponse getUserLoginDayCount() {
        Integer dayCount = this.userService.getLoginDayCount();
        return new HttpResponse(ResponseEnum.SUCCESS, dayCount);
    }

    /**
     * 修改用户信息
     *
     * @param userInfoMap 用户信息Map
     * @return 是否修改成功
     */
    @PostMapping("/update-info")
    @Transactional
    public HttpResponse updateUserInfo(@RequestBody Map<String, String> userInfoMap) {
        String name = userInfoMap.get("name");
        String birthday = userInfoMap.get("birthday");
        String gender = userInfoMap.get("gender");

        // 更新用户信息
        this.userService.updateUserInfo(name, birthday, gender);

        return new HttpResponse(ResponseEnum.SUCCESS_UPDATE_USER_INFO, null);
    }
}
